<?php
// +----------------------------------------------------------------------
// | ZGUAN [ 致力于帮助更多的中小同住人员物联网转型 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.zguan.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ZGUAN 并不是自由软件，未经许可不能去掉ZGUAN 相关版权
// +----------------------------------------------------------------------
// | Author: ZGUAN Team <admin@zguan.cn>  0769-82282996  15899929162
// +----------------------------------------------------------------------
namespace app\controller\api\contract;

use think\App;
use app\controller\property\Base;
use app\common\services\CacheService;
use app\validate\contract\ContractBasicValidate;
use app\common\repositories\room\RoomBasicRepository;
use app\common\repositories\contract\ContractBasicRepository;
use app\common\repositories\property\basic\PropertyBasicRepository;


class ContractBasic extends Base
{
    protected $repository;

    public function __construct(App $app, ContractBasicRepository $repository)
    {
        parent::__construct($app);

        $this->repository = $repository;

    }

    public function getStatistics(int $id)
    {
        if ($id > 0) {
            /** @var PropertyBasicRepository $propertyBasicRepository */
            $propertyBasicRepository = app()->make(PropertyBasicRepository::class);
            if (!$propertyBasicRepository->existsByUserId($id, $this->request->userId())) {
                return app('api_return')->error('权限不足');
            }
        }
        $res = CacheService::create($this->request->propertyId)
            ->remember('contract_survey_property_' . $id, function () use ($id) {
                return $this->repository->getStatistics($id);
            }, 3600);
        return app('api_return')->success($res);
    }


    /**
     *  获取合同列表
     * @return string|\think\response\Json|\think\response\View
     *
     * @author Amos
     * 2024-06-13 23:28
     */
    public function contractList()
    {
        $where = $this->request->param([
            'room_id' => '',
            'status' => '',
            'sign_type' => '',
            'property_id' => '',
            'keywords' => '',
        ]);
        [$page, $limit] = $this->getPage();
        $res = $this->repository->getApiList($where, $page, $limit, $this->request->propertyId);
        return app('api_return')->success($res);
    }


    /**
     * 获取合同编号
     * @return mixed
     *
     * @author Amos
     * 2024-06-13 19:49
     */
    public function getCode(int $id)
    {
        if ($id > 0) {
            /** @var PropertyBasicRepository $propertyBasicRepository */
            $propertyBasicRepository = app()->make(PropertyBasicRepository::class);
            if (!$propertyBasicRepository->existsByUserId($id, $this->request->userId())) {
                return app('api_return')->error('权限不足');
            }
        }
        $res = $this->repository->generateContractNumber($id);
        return app('api_return')->success($res);
    }

    /**
     *  创建合同
     * @return mixed
     *
     * @author Amos
     * 2024-06-13 20:41
     */
    public function addContract()
    {
        $param = $this->request->param([
            'property_id' => '',
            'room_id' => '',
            'rent_date' => '',
            'room_rent' => '',
            'room_deposit' => '',
            'pay_type' => '',
            'sign_type' => '',
            'number' => '',
            'start_date' => '',
            'end_date' => '',
            'bill_month' => '',
            'bill_pay_day' => '',
            'bill_add_day' => '',
            'bill_prompt' => '',
            'overdue_fine' => '',
            'remark' => '',
            'out_fee_flag' => '',
            'is_rose' => '',
            'next_years' => '',
            'next_rose_rate' => '',
            'next_rose_date' => '',
            'next_rose_rent' => '',
            'picture' => [],
            'other_fee' => [],
            'lessee_info' => [],
            'end_method' => '',
            'sign_audit' => '',
            'template_id' => '',
        ]);
        validate(ContractBasicValidate::class)->scene('add')->check($param);

        if ($param['property_id'] > 0) {
            /** @var PropertyBasicRepository $propertyBasicRepository */
            $propertyBasicRepository = app()->make(PropertyBasicRepository::class);
            if (!$propertyBasicRepository->existsByUserId($param['property_id'], $this->request->userId())) {
                return app('api_return')->error('权限不足');
            }
        }
        if ($this->repository->fieldExists('number', $param['number'])) {
            return app('api_return')->error('租赁编号' . $param['number'] . ' 已存在');
        }
        $res = $this->repository->addInfo($param, $this->request->propertyId, $this->request->userId());
        return app('api_return')->success($res['id']);
    }

    /**
     * 编辑合同
     * @param int $id
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-06-13 20:59
     */
    public function editContract(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $param = $this->request->param([
            'is_rose' => '',
            'next_years' => '',
            'next_rose_rate' => '',
            'next_rose_date' => '',
            'next_rose_rent' => '',
            'bill_add_day' => '',
            'bill_month' => '',
            'bill_prompt' => '',
            'bill_pay_day' => '',
            'overdue_fine' => '',
            'sign_type' => '',
            'sign_audit' => '',
            'end_method' => '',
            'picture' => [],
            'remark' => '',
            'out_fee_flag' => '',
            'template_id' => '',
        ]);
        validate(ContractBasicValidate::class)->scene('edit')->check($param);
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('信息错误');
        }
        $res = $this->repository->editInfo($info, $param, $this->request->userId());
        return app('api_return')->success($res);
    }

    /**
     * 删除合同
     * @param int $id
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-06-13 20:59
     */
    public function delete(int $id)
    {
        if (!$this->repository->exists($id)) {
            return app('api_return')->error('数据不存在');
        }
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }

        if ($info['property_id'] > 0) {
            /** @var PropertyBasicRepository $propertyBasicRepository */
            $propertyBasicRepository = app()->make(PropertyBasicRepository::class);
            if (!$propertyBasicRepository->existsByUserId($info['property_id'], $this->request->userId())) {
                return app('api_return')->error('权限不足');
            }
        }
        $res = $this->repository->batchDelete([$id], $this->request->userId());
        if ($res) {
            return app('api_return')->success('删除成功');
        } else {
            return $this->error('删除失败');
        }
    }

    /**
     * 合同详情
     * @param int $id
     * @return string|\think\response\Json|\think\response\View
     *
     * @author Amos
     * 2024-06-13 20:59
     */
    public function detail(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $info = $this->repository->getApiDetail($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        return app('api_return')->success($info);
    }


    /**
     * 合同续租
     * @param int $id
     * @return string|\think\response\Json|\think\response\View
     *
     * @author Amos
     * 2024-06-13 20:59
     */
    public function extendContract(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $param = $this->request->param([
            'end_date' => '',
        ]);
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        if ($info['status'] != 2) {
            return app('api_return')->error('此租赁不可进行此操作');
        }
        if ($param['end_date'] <= $info['end_date']) {
            return $this->error('续租日期必须大于结束日期');
        }
        $res = $this->repository->extendContract($id, $param['end_date'], $this->request->userId());
        return app('api_return')->success($res);
    }


    /**
     * 合同审核
     * @param int $id
     * @return string|\think\response\Json|\think\response\View
     *
     * @author Amos
     * 2024-06-13 20:59
     */
    public function auditContract(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $param = $this->request->param([
            'status' => '',
            'remark' => '',
        ]);
        validate(ContractBasicValidate::class)->scene('audit')->check($param);
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        if ($info['status'] != 1) {
            return app('api_return')->error('此租赁状态不可审核');
        }
        $res = $this->repository->auditSuccess($id, $param['status'], $this->request->userId(), $param['remark']);
        return app('api_return')->success($res);
    }

    /**
     *  合同退租
     * @param int $id
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-06-13 22:01
     */
    public function renunContract(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $param = $this->request->param([
            'refund_type' => '',
            'remark' => '',
        ]);
        validate(ContractBasicValidate::class)->scene('renun')->check($param);
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        if ($info['status'] != 2) {
            return app('api_return')->error('此租赁不可进行此操作');
        }
        $res = $this->repository->refundContract($info['id'], $param, $this->request->userId());
        return app('api_return')->success($res);
    }

    /**
     *  合同作废
     * @param int $id
     * @return string|\think\response\Json|\think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     *
     * @author Amos
     * 2024-06-13 22:01
     */
    public function invalidContract(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $param = $this->request->param([
            'remark' => '',
        ]);
        validate(ContractBasicValidate::class)->scene('invalid')->check($param);
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        if ($info['status'] != 1) {
            return app('api_return')->error('此租赁不可进行此操作');
        }
        $res = $this->repository->invalidContract($info['id'], $param, $this->request->userId());
        return app('api_return')->success($res);
    }


    /**
     * 根据合同 ID 获取空置房间
     * @return mixed
     *
     * @author Amos
     * 2024-06-13 22:29
     */
    public function vacancyList(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $param = $this->request->param([
            'unit_id' => '',
            'keywords' => '',
        ]);
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        if ($info['status'] != 1 && $info['status'] != 2) {
            return app('api_return')->error('此租赁不可进行此操作');
        }
        [$page, $limit] = $this->getPage();
        $param['status'] = 1;
        $param['property_id'] = $info['property_id'];
        /** @var RoomBasicRepository $roomBasicRepository */
        $roomBasicRepository = app()->make(RoomBasicRepository::class);
        $res = $roomBasicRepository->getApiContractIdVacancyiList($param, $page, $limit, $this->request->propertyId);
        return app('api_return')->success($res);
    }

    /**
     * 根据合同 ID 获取关联房间
     * @return mixed
     *
     * @author Amos
     * 2024-06-13 22:29
     */
    public function bindRoomList(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        [$page, $limit] = $this->getPage();
        $param['contract_id'] = $id;
        /** @var RoomBasicRepository $roomBasicRepository */
        $roomBasicRepository = app()->make(RoomBasicRepository::class);
        $res = $roomBasicRepository->getApiContractIdVacancyiList($param, $page, $limit, $this->request->propertyId);
        return app('api_return')->success($res);
    }

    /**
     * 合同关联房间
     * @return mixed
     *
     * @author Amos
     * 2024-06-13 22:29
     */
    public function roomBound(int $id)
    {
        if (!$this->repository->exists($id)) {
            return $this->error('数据不存在');
        }
        $param = $this->request->param([
            'room_id' => '',
        ]);
        $info = $this->repository->get($id);
        if (!$info) {
            return app('api_return')->error('数据不存在');
        }
        if ($info['status'] != 1 && $info['status'] != 2) {
            return app('api_return')->error('此租赁不可进行此操作');
        }
        $this->repository->batchRoomBound($info, $param['room_id'], $this->request->userId());
        return app('api_return')->success('关联成功');
    }

}